/**
 * Created by 余华杰 on 2015/5/30.
 */
define(['jquery'],function(jquery){

    /*
     * address 指令地址
     */
    function randomAddress(){
        var address=new Array(0);
        /*
         * d 取初始的地址为中间的地址
         */
        var d=parseInt(Math.random()*12345);

        for (var i=0;i<30;i++){
            //用于判断下一个地址应该取值的方法
            var a=Math.random()*1024;

            /*
             * 1<a<512    d[i++]=d[i]+1;
             * 512<a<768  d[i++]=1~d之间;
             * 768<a<1024 d[i++]=d[i]~32767之间
             */
            if(a>=1&&a<=512){
                d=d+1;
                address.push(d);
            }
            else if(a>512&&a<=768){
                d=parseInt(Math.random()*d);
                address.push(d);
            }
            else {
                d=parseInt(Math.random()*d+(32767-d));
                address.push(d);
            }
        }
        return address;
    }

    /*
     * 合并相邻的且相同地址
     * @param address 产生的256个随机地址
     * @param page_length 页面的大小
     */
    function page(address,page_length){
        var queue=new Array(0);
        var length=address.length;
        var index=0;
        while(index<length){
            var temp=parseInt(Math.abs(address[index]/page_length));  //对应的页面
            var j=index+1;
            /*
             * 如果相等，则是相邻的页面；直到不相等为止，这样一直查询下去，最后得到的就是合并后的压面
             */
            while(temp==parseInt(Math.abs(address[j]/page_length))){
                j++;
            }
            index=j;
            queue.push(temp);
        }

        return queue;
    }

    var OPT=1;
    var FIFO=2;
    var LRU=3;


    /*
     * 判断块是否已经分配完
     */
    function isFull(blocks,length){
        if(blocks.length==length)
            return true;
        else
            return false;
    }

    /*
     * 判断是否在快中
     */
    function in_array(blocks,param)
    {
        for(var i=0;i<blocks.length;i++)
        {
            if(param==blocks[i])
                return {result:true,index:i};
        }
        return {result:false};
    }

    /*
     * blocks中最迟出现的页面
     */
    function the_last(temp)
    {
        var max=temp[0];
        var k=0;
        for(var i=1;i<temp.length;i++)
        {
            if(max<temp[i])
            {
                max=temp[i];
                k=i;
            }
        }
        return k;
    }

    /*
     * opt算法
     * @param pages 页面
     */
    function PROGRAM_OPT(pages,length){
        var interrupt=0;//中断次数
        var blocks=new Array(0);
        for(var i=0;i<pages.length;i++)
        {
            if(in_array(blocks,pages[i]).result)
                continue;
            else
            {
                if(isFull(blocks,length))
                {
                    var temp=new Array(length); //存放块中最早出现的时候
                    for(var j=0;j<length;j++)
                    {
                        temp[j]=0;
                        for(var k=i+1;k<pages.length;k++)
                        {
                            if(blocks[j]!=pages[k])
                                temp[j]++;
                            else
                                break;
                        }
                    }
                    var last=the_last(temp);  //最晚出现的块的下标
                    blocks[last]=pages[i];
                }
                else
                    blocks.push(pages[i]);
                interrupt++; //中断次数+1
            }

        }

        return {
            interrupt:interrupt,
            interrupt_rate:parseFloat(interrupt/pages.length)*100
        }
    }

    /*
     * fifo算法
     * @param pages 页面
     */
    function PROGRAM_FIFO(pages,length){
        var blocks=new Array(0);
        var interrupt=0;
        for(var i=0;i<pages.length;i++)
        {
            if(in_array(blocks,pages[i]).result)
                continue;
            else
            {
                if(isFull(blocks,length))
                {
                    blocks.shift();
                }
                blocks.push(pages[i]);
                interrupt++;
            }

        }
        return {
            interrupt:interrupt,
            interrupt_rate:parseFloat(interrupt/pages.length)*100
        }
    }

    /*
     * 设置计数器为0,重新计时
     * @param count 计数器
     */
    function setRestart(count)
    {
        for(var i=0;i<count.length;i++)
            count[i]=0;
    }

    /*
     * 设置计数器
     */
    function setCount(count){
        for(var i=0;i<count.length;i++)
            count[i]++;
    }

    /*
     * lru算法
     */
    function PROGRAM_LRU(pages,length){
        var blocks=new Array(0);
        var interrupt=0;
        var count=new Array(length);
        setRestart(count);//初始化计数器
        for(var i=0;i<pages.length;i++) {
            if (in_array(blocks, pages[i]).result) {
                var index = in_array(blocks, pages[i]).index;
                setCount(count);
                count[index] = 0;
                continue;
            }
            else {
                if (isFull(blocks, length)) {
                    var last = the_last(count);
                    blocks[last] = pages[i];
                    setCount(count);
                    count[last] = 0;//重新计时
                }
                else {
                    for (var k = 0; k < blocks.length; k++) {
                        count[k]++;
                    }
                    blocks.push(pages[i]);
                    count[blocks.length - 1] = 0;//新进入的页面
                }
                interrupt++;
            }
        }
        return {
            interrupt:interrupt,
            interrupt_rate:parseFloat(interrupt/pages.length)*100
        }

    }

    /*
     * 运行算法
     * @param kind 算法的种类
     * @param pages 页面
     * @param blocks 快
     */
    function run(kind,pages,length){
        switch(kind)
        {
            case OPT:return PROGRAM_OPT(pages,length);break;
            case FIFO:return PROGRAM_FIFO(pages,length);break;
            case LRU:return PROGRAM_LRU(pages,length);break;
        }
    }



    return {
        create: function(page_length){
            var address=randomAddress();  //产生随机地址
            return page(address,page_length); //产生合并好的地址
        },
        run:function(kind,pages,length){
            var result=run(kind,pages,length);
            $("#interrupt").text(result.interrupt);
            var result_interrupt_rate=String(result.interrupt_rate);
            result_interrupt_rate=result_interrupt_rate.substring(0,result_interrupt_rate.indexOf(".")+3);
            $("#interrupt_rate").text(result_interrupt_rate+"\%");

        }
    };
});